package top.pushtothe.Tree

class TreeNode<T> constructor(
	var childrenRef: ArrayList<TreeNode<T>> = ArrayList<TreeNode<T>>(),
	var data: T? = null

) {
	constructor(data:T?):this(ArrayList<TreeNode<T>>(),data){
		
	}


	fun getTree(node: TreeNode<T>): LinkedHashSet<TreeNode<T>> {
		var tree = LinkedHashSet<TreeNode<T>>()
		tree.add(node)

		return tree
	}

	fun addNode(node: TreeNode<T>) {
		childrenRef.add(node)
	}
	fun addNodeReturn(node:TreeNode<T>):TreeNode<T>{
		childrenRef.add(node)
		return node
		
	}

	fun clearNode() {
		data = null
		childrenRef.clear()
	}

	fun getChildAtIndex(index: Int): TreeNode<T> {
		return childrenRef.get(index)
	}

	fun getFirstChild(): TreeNode<T> {
		//get(0)
		return childrenRef.first()
	}

	fun getLastChild(): TreeNode<T> {
		//get(childrenRef.size()-1)
		return childrenRef.last()
	}

	fun getChildren(): ArrayList<TreeNode<T>> {
		return childrenRef
	}


	//get root data
	fun getRootData(): T? {
		return data

	}

	fun isEmpty(): Boolean {
		if (childrenRef.isEmpty() && data == null) {
			return true
		}
		return false

	}

	fun isLeaf(): Boolean {
		if (childrenRef.isEmpty()) {
			return true
		}
		return false
	}

	fun root(): TreeNode<T> {
		return this
	}

	//set root data
	fun setDataOfRoot(data: T) {
		this.data = data

	}

	//get count of nodes
	fun countOfNodes(): Int {
		return size(this)
	}

	private fun size(node: TreeNode<T>): Int {
		if (node.isEmpty()) {
			return 0

		} else if (node.isLeaf()) {
			return 1
		} else {
			var nodeCount: Int = 1
			var n: Int = childrenRef.count()
			for (i in 0..(n-1)) {
				if (!childrenRef.get(i).isEmpty()) {
					println("in size(), i:$i")
					nodeCount += size(childrenRef.get(i))
				}
			}
			return nodeCount
		}
	}

}